#include "work_stack.h"
//工作栈构造函数  
//在算符栈栈底插入栈底算符 并 将变量栈栈顶指针初始化
work_stack::work_stack(){
	TOKEN temp = {"",-1};
	insert_symbol(temp);
	IP_number = 0;
	start_location = 0;
	temp_var_number = 0;
	layout_number = 1;
}
//变量栈进栈
//@param int type  进栈的变量类型
void work_stack::insert_variable(int type){
	var_stack.push_back(type);
}
void work_stack::insert_value(string value){
	value_stack.push_back(value);
}
//算符栈进栈
//如果是‘ ｛ ’则将栈顶指针指向栈顶		
//WHILE进栈时将此时的IP位置存进while_flag栈  while.start
//THEN进栈时存入 IF Q ，GOTO IP+2 ， GOTO ｛else.start / then.end｝三条指令
//ELSE进栈时存入 GOTO ｛else.end｝并  回填 else.start
//DO进栈时存入 IF Q ，GOTO IP+2 ， GOTO ｛do.end｝三条指令
//@param   TOKEN token  进栈的字符
void work_stack::insert_symbol(TOKEN token){
	int new_symbol = token.token_type;
	if( new_symbol == WHILE){
		while_flag.push_back(IP_number);
	}
	if( new_symbol == DO){
		list.insert(IF, value_stack.back());
		IP_number ++;
		list.insert_goto(IP_number+2);
		list.insert_goto();
		list.insert_back_point(IP_number+1);	
		IP_number += 2;
	}
	if( new_symbol == THEN){
		list.insert(IF, value_stack.back());
		IP_number ++;
		list.insert_goto(IP_number+2);
		list.insert_goto();
		list.insert_back_point(IP_number+1);	
		IP_number += 2;
	}
	if( new_symbol == ELSE){
		list.insert_goto();	
		list.insert_back_point(IP_number);	
		list.back_to_fill(IP_number+1);
		IP_number ++;
	}
	if( new_symbol == LEFT_MIDDLE_BRACKET){
		layout_number ++;
		start_location = var_stack.size();
		duan_top.push_back(start_location);
	}
	symbol_stack.push_back(token);
}
//算符栈出栈  弹出栈顶优先级相同的所有算符    a<b=c=d=e>f
void work_stack::pop_symbol(){
	vector<TOKEN>::iterator it = symbol_stack.end() - 1;
	//检查优先级
	while(token_level[(*(it-1)).token_type][(*it).token_type] == 2){
		 it = symbol_stack.erase(it) - 1; 
	}
	symbol_stack.erase(symbol_stack.end()-1);
}
//变量栈出栈   弹出栈顶变量
void work_stack::pop_var(){
	var_stack.erase(var_stack.end()-1);
}
void work_stack::pop_value(){
	value_stack.erase(value_stack.end()-1);
}
//‘｛｝’内变量出栈  
//@return bool 成功true  失败false
//@throws 检查程序段内是够所有变量都已经归约成功
bool work_stack::pop_DUAN(){
	for (int length = var_stack.size() ;length > duan_top.back(); length = var_stack.size()){
		if(var_stack.back() != S){
			return false;
		} 
		pop_var();
	}
	duan_top.pop_back();
	return true;
}
//生成中间变量的函数
void work_stack::make_node(string &temp_var, int temp_var_number){
	char middle;
	temp_var += '$';
	string temp;
	middle = temp_var_number%10 + 48;
	temp += middle;	
	temp_var_number /= 10;
	for(; temp_var_number > 0; temp_var_number = temp_var_number/10){
		middle = temp_var_number%10 + 48;
		temp += middle;	
	}
	for(int i = temp.length() - 1; i >= 0; i--){
		temp_var += temp[i];
	}
}
//归约操作
//@param int new_symbol
//@return bool 归约是否成功
//@throws 变量栈内的变量与符号栈顶符号匹配失败时返回false
bool work_stack::reduce(TOKEN token){
	int new_symbol = token.token_type;
	int check = 0;
	int top = symbol_stack.back().token_type;
	if(new_symbol >= INT10 && new_symbol <= FLOAT16){
		new_symbol = INT10;
	}
	if(top >= INT10 && top <= FLOAT16){
		top = INT10;
	}
	//V->id
	if(top == VARIABLE){
		insert_variable(V);
		insert_value(symbol_stack.back().name);
		pop_symbol();
		cout<<"V->id"<<endl;
		try_insert(token);
		return true;
	}
	//NUMBER->number
	if(top >= INT10){
		insert_variable(NUMBER);
		insert_value(symbol_stack.back().name);
		pop_symbol();
		cout<<"NUMBER->number"<<endl;
		try_insert(token);
		return true;
	}
	//生成 temp = x > y 的三地址码
	//IP++
	if(top == GT){
		check = (var_stack.back() >= P) + (*(var_stack.end()-2) >= Q);
		if(check == 2){
			string temp_number;
			
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_var();
			string temp2 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(Q);
			temp_var_number++;
			make_node(temp_number, temp_var_number);
			insert_value(temp_number);
			
			
			list.insert(GT,temp_number,temp2,temp1);
			IP_number ++;
			cout<<"Q-> Q > P"<<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//生成 temp = x < y 的三地址码
	//IP++
	if(top == LT){
		check = (var_stack.back() >= P) + (*(var_stack.end()-2) >= Q);
		if(check == 2){
			string temp_number;
			
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_var();
			string temp2 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(Q);
			temp_var_number++;
			make_node(temp_number, temp_var_number);
			insert_value(temp_number);
			
			list.insert(LT,temp_number,temp2,temp1);
			IP_number ++;
			cout<<"Q-> Q < P"<<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//生成 temp = x >= y 的三地址码
	//IP++
	if(top == GE){
		check = (var_stack.back() >= P) + (*(var_stack.end()-2) >= Q);
		if(check == 2){
			string temp_number;
			
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_var();
			string temp2 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(Q);
			temp_var_number++;
			make_node(temp_number, temp_var_number);
			insert_value(temp_number);
			
			list.insert(GE,temp_number,temp2,temp1);
			IP_number ++;
			cout<<"Q-> Q >= P"<<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//生成 temp = x <= y 的三地址码
	//IP++
	if(top == LE){
		check = (var_stack.back() > P) + (*(var_stack.end()-2) > Q);
		if(check == 2){
			string temp_number;
			
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_var();
			string temp2 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(Q);
			temp_var_number++;
			make_node(temp_number, temp_var_number);
			insert_value(temp_number);
			
			list.insert(LE,temp_number,temp2,temp1);
			IP_number ++;
			cout<<"Q-> Q <= P"<<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//生成 temp = x == y 的三地址码
	//IP++
	if(top == EQUAL){
		check = (var_stack.back() > P) + (*(var_stack.end()-2) > Q);
		if(check == 2){
			string temp_number;
			
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_var();
			string temp2 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(Q);
			temp_var_number++;
			make_node(temp_number, temp_var_number);
			insert_value(temp_number);
			
			list.insert(EQUAL,temp_number,temp2,temp1);
			IP_number ++;
			cout<<"Q-> Q == P"<<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//生成 temp = x + y 的三地址码
	//IP++
	if(top == PLUS){
		check = (var_stack.back() >= M) + (*(var_stack.end()-2) >= P);
		if(check == 2){
			string temp_number;
			
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_var();
			string temp2 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(Q);
			temp_var_number++;
			make_node(temp_number, temp_var_number);
			insert_value(temp_number);
			
			list.insert(PLUS,temp_number,temp2,temp1);
			IP_number ++;
			cout<<"P -> P + M"<<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//生成 temp = x - y 的三地址码
	//IP++
	if(top == MINUS){
		check = (var_stack.back() >= M) + (*(var_stack.end()-2) >= P);
		if(check == 2){
			string temp_number;
			
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_var();
			string temp2 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(Q);
			temp_var_number++;
			make_node(temp_number, temp_var_number);
			insert_value(temp_number);
			
			list.insert(MINUS,temp_number,temp2,temp1);
			IP_number ++;
			cout<<"P -> P - M"<<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//生成 temp = x * y 的三地址码
	//IP++
	if(top == MULTIPLY){
		check = (var_stack.back() >= E) + (*(var_stack.end()-2) >= M);
		if(check == 2){
			string temp_number;
			
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_var();
			string temp2 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(Q);
			temp_var_number++;
			make_node(temp_number, temp_var_number);
			insert_value(temp_number);
			
			list.insert(MULTIPLY,temp_number,temp2,temp1);
			IP_number ++;
			cout<<"M -> M * E"<<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//生成 temp = x / y 的三地址码
	//IP++
	if(top == DEVIDE){
		check = (var_stack.back() >= E) + (*(var_stack.end()-2) >= M);
		if(check == 2){
			string temp_number;
			
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_var();
			string temp2 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(Q);
			temp_var_number++;
			make_node(temp_number, temp_var_number);
			insert_value(temp_number);
			
			list.insert(DEVIDE,temp_number,temp2,temp1);
			IP_number ++;
			cout<<"M -> M / E"<<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//生成  x = y 的三地址码
	//IP++
	if(top == ASSIGNMENT){
		check = (var_stack.back() >= Q);
		if(*(var_stack.end()-2) == V){
			check++;
			cout<<"A->V = Q"<<endl;
		}
		if(*(var_stack.end()-2) == L){
			check++;
			cout<<"A->L = Q"<<endl;
		}
		if(check == 2){	
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_var();
			string temp2 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(A);
			insert_value("1");
			
			list.insert(ASSIGNMENT,temp2,temp1);
			IP_number ++;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//右括号归约
	if(top == RIGHT_BRACKET){
		if(var_stack.back() >= Q){
			string temp_number;
			
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_symbol();
			cout<<"E -> ( Q )"<<endl;
			
			insert_variable(E);
			insert_value(temp1);
			
			try_insert(token);
		}
		return true;
	}
	//G-> if Q then DUAN  的归约
	//回填 then.end
	if(top == THEN){
		check = (*(var_stack.end()-2) >= Q);
		if(var_stack.back() == DUAN || var_stack.back() == S || (var_stack.back() >= A && var_stack.back() <= L)){
			check++;
		}
		if(check == 2){
			pop_var();
			pop_value();
			
			pop_var();
			pop_value();
			
			pop_symbol();
			
			list.back_to_fill(IP_number);
			cout<<"G-> if Q then DUAN"<<endl;
			insert_variable(G);
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//G-> if Q then DUAN else DUAN  的归约
	//回填 else.end
	if(top == ELSE){
		check = (*(var_stack.end()-3) >= Q);
		if(var_stack.back() == DUAN || var_stack.back() == S || (var_stack.back() >= A && var_stack.back() <= L)){
			check++;
		}
		if(*(var_stack.end()-2) == DUAN || *(var_stack.end()-2) == S || (var_stack.back() >= A && var_stack.back() <= L)){
			check++;
		}
		if(check == 3){
			pop_var();
			pop_value();
			
			pop_var();
			pop_value();
			
			pop_var();
			pop_value();
			
			pop_symbol();
			
			list.back_to_fill(IP_number);
			cout<<"G-> if Q then DUAN else DUAN"<<endl;
			insert_variable(G);
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//回填  do.end
	//生成  GOTO｛while.start｝的指令
	if(top == DO){
		check = (*(var_stack.end()-2) >= Q);
		if(var_stack.back() == DUAN || var_stack.back() == S || (var_stack.back() >= A && var_stack.back() <= L)){
			check++;
		}
		if(check == 2){
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_var();
			string temp2 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			list.back_to_fill(IP_number+1);
			list.insert_goto(while_flag.back());
			while_flag.pop_back();
			IP_number ++;
			cout<<"H-> while Q do DUAN"<<endl;
			insert_variable(H);
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//DUAN-> { S } 的归约
	if(top == RIGHT_MIDDLE_BRACKET){
		if(pop_DUAN()){
			layout_number--;
			pop_symbol();
			cout<<"DUAN-> { S }"<<endl;
			insert_variable(DUAN);
			
			try_insert(token);
			return true;
		}else{
			cout<<"DUAN error";
			return false;
		}
		
	}
	//生成 INT x 指令
	if(top == INT){
		check = (var_stack.back() == V);
		if(check){
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(N);
			insert_value(temp1);
			
			list.insert(INT,temp1);
			IP_number ++;
			cout<<"N-> int V" <<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//生成  CHAR x 指令
	if(top == CHAR){
		check = (var_stack.back() == V);
		if(check){
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(C);
			insert_value(temp1);
			
			list.insert(CHAR,temp1);
			IP_number ++;
			cout<<"C-> char V" <<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//生成  FLOAT x 指令
	if(top == FLOAT){
		check = (var_stack.back() == V);
		if(check){
			pop_var();
			string temp1 = value_stack.back();
			pop_value();
			
			pop_symbol();
			
			insert_variable(F);
			insert_value(temp1);
			
			list.insert(FLOAT,temp1);
			IP_number ++;
			cout<<"F-> float V" <<endl;
			try_insert(token);
		}else{
			cout<<"error";
			return false;
		}
		return true;
	}
	//对一句表达式进行归约
	if(top == SEMICOLON){
		if(var_stack.back() == A){
			cout<<"S-> A ;" <<endl;
			check = 1 ;
		}
		else if(var_stack.back() == L){
			pop_value();
			cout<<"S-> L ;" <<endl;
			check = 1 ;
		}
		else if(var_stack.back() == G){
			cout<<"S-> G ;" <<endl;
			check = 1 ;
		}
		else if(var_stack.back() == H){
			cout<<"S-> H ;" <<endl;
			check = 1 ;
		}
		if(check){
			pop_var();
			pop_symbol();
			insert_variable(S);
			try_insert(token);
		}else{
			pop_symbol();
			try_insert(token);
		}
		return true;
	}
}
//算符尝试进栈  优先级低于栈顶元素归约  小于或等于则进栈  0表示错误
//@param TOKEN token	进栈算符
//@return 进栈是否成功  否则报错
bool work_stack::try_insert(TOKEN token){
	if(token.token_type >= INT10 && token.token_type <= FLOAT16){
		token.token_type = INT10;
	}
	int new_symbol = token.token_type;

	// vector<int>::iterator it=symbol_stack.begin();
	// cout<<"symbol:";
	// for(it=symbol_stack.begin();it!=symbol_stack.end();it++)
	// 	cout<<(*it)<<",";
		
	// it=var_stack.begin();
	// cout<<endl<<"variable:";
	// for(it=var_stack.begin();it!=var_stack.end();it++)
	// 	cout<<(*it)<<",";
	// cout<<endl;
	if(symbol_stack.back().token_type == -1){
		insert_symbol(token);
		return true;
	}
	int check = 0;
	vector<TOKEN>::iterator it=symbol_stack.begin();
	vector<int>::iterator ite= var_stack.begin();
	//cout<<symbol_stack.back()<<","<<new_symbol<<","<<token_level[symbol_stack.back()][new_symbol]<<endl;
	switch(token_level[symbol_stack.back().token_type][new_symbol]){
		case 0:
			cout<<"symbol:";
			for(it=symbol_stack.begin();it!=symbol_stack.end();it++)
				cout<<(*it).token_type<<",";
			cout<<endl<<"variable:";
			for(ite=var_stack.begin();ite!=var_stack.end();ite++){
				cout<<(*ite)<<",";
				if(*ite != S){
					check++;
				}
			}
			cout<<endl;
			return false;
			break;
		case -1:
			insert_symbol(token);
			return true;
			break;
		case 2:
			insert_symbol(token);
			return true;
			break;
		case 1:
			return reduce(token);
			break;	
	}
}
//检查是否所有算符和变量归约完成
//@return bool 归约结果
bool work_stack::if_succeed(){
	int check = 0;
	vector<TOKEN>::iterator it=symbol_stack.begin();
	cout<<"symbol:";
	for(it=symbol_stack.begin();it!=symbol_stack.end();it++)
		cout<<(*it).token_type<<",";
	vector<int>::iterator ite= var_stack.begin();
	cout<<endl<<"variable:";
	for(ite=var_stack.begin();ite!=var_stack.end();ite++){
		cout<<(*ite)<<",";
		if(*ite != S){
			check++;
		}
	}
	cout<<endl;
	if(symbol_stack.size() == 2 && check == 0){
		list.insert(END);
		list.display();
		return true;
	}else{
		return false;
	}
}

